<?php

namespace Chat\Controller;

use Org\Net\Socket;
use Think\Controller;

/**
 * Chat服务
 */
class StartController extends Controller {

    //socke服务Driver
    private $server = null;

    /**
     * 服务启动
     */
    public function index() {
        set_time_limit(0);
        $this->server = new Socket();

        $controller = $this;
        $this->server->bind('message', function ($client_id, $message, $messageLength, $binary) use ($controller) {
            $message = json_decode($message, true);
            
            //无字节则关闭链接
            if ($messageLength == 0)
                return $this->server->wsClose($client_id);

            //创建对应关系
            if (!$controller->relation($client_id, $message['sender'], $message['receiver']))
                return false;

            //空数据时不发送
            if ($message['text'] == '')
                return false;
            
            return $controller->send($message['sender'], $message['receiver'], $message['text']);
        });

        //链接关闭时触发
        $this->server->bind('close', function ($client_id, $status) use ($controller) {
            $controller->unrelation($client_id);
        });

        //启动服务
        $this->server->wsStartServer('0.0.0.0', 8000);
    }

    /**
     * 发送信息
     * @param mixed $sender 发送者
     * @param mixed $receiver 接收者
     * @param string $content 内容
     * @return mixed  id|false
     */
    public function send($sender, $receiver, $content) {
        $User = M("Chat"); // 实例化User对象
        $data = array('sender' => $sender, 'receiver' => $receiver, 'content' => $content);
        
        if (F($receiver)) {
            $data['has_read'] = '1';
            $this->server->wsSend(F($receiver), $content);
        }
        
        return $User->add($data);
    }

    /**
     * 生成关系
     * @param int $client_id 链接id
     * @param string $sender 发送者唯一标识
     * @param string $receiver 接收者唯一标识
     * @return mixed 失败返回false|null 成功返回关系数组
     */
    public function relation($client_id, $sender, $receiver) {
        if (!($client_id && $sender && $receiver))
            return false;

        //不存在则创建关系
        if (!$relation = json_decode(F($client_id), true)) {
            F($sender, $client_id);
            F($client_id, json_encode(array('sender' => $sender, 'receiver' => array($receiver => $receiver))));
        }

        //1:N关系 增加关系
        if ($relation && F($client_id) && F($sender) && !isset($relation['receiver'][$receiver]))
            $relation['receiver'][$receiver] = $receiver && F($client_id, json_encode($relation, true));

        return $relation;
    }

    /**
     * 解除关系
     * @param int $client_id 链接id
     * @return boolean 返回操作状态
     * @todo 由于TP机制不好可能会造成 操作成功但返回为false
     */
    public function unrelation($client_id) {
        //不存在则返回失败不继续执行
        if (!$relation = json_decode(F($client_id), true))
            return false;

        F($client_id, null);
        F($relation['sender'], null);
        return true;
    }

}
